<?php
/**
 * 当前项目的应用执行脚本
 * @author  ZhouHaoHua <53027327@qq.com>
 * @package
 */
class Application extends \core\models\Application {
    /**
     * 控制器的代表参数名
     * @var string
     */
    public $arg_controller_name = 'mod';
    /**
     * 动作方法的代表参数名
     * @var string
     */
    public $arg_action_name = 'action';

    /**
     * 执行视图处理输出
     */
    public function runView() {
        //发送heaer标记
        /*header('Content-type: text/html; charset='. Z_CHARSET_PROJECT);
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
        header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
        header('Access-Control-Allow-Credentials:true');*/
        //echo Z_CHARSET_PROJECT;exit;
        $c          = $this->controller;
        $this->data = $c->data;
        /**
         * 视图文件夹路径
         */
        $viewsPath = Z_APP . '/views';
        if ($c->data) {
            $errors = error_get_last();
            if (!$errors) {
                $gzip = new \core\models\Gzip();
                $gzip->ob_start();
            }

            if ($c->tplTop || $c->tplContent || $c->tplBottom) {
                $metaArr = array();
                $html              = new \Html('zh_CN', $c->metaCharset);
                $html->title       = $c->metaTitle;
                $html->description = $c->metaDescription;
                $html->keywords    = $c->metaKeywords;
                $html->tplTop      = $viewsPath . '/' . str_replace('_', '/', $c->tplTop);
                $html->tplContent  = $viewsPath . '/' . str_replace('_', '/', $c->tplContent);
                $html->tplBottom   = $viewsPath . '/' . str_replace('_', '/', $c->tplBottom);
                //按规则自动设置JS和CSS
                if ($c->tplContent) {
                    //$fCSS[] = '/' . Z_TOP_WWW . '/views/css/reset.css';
                    //$fCSS[] = '/' . Z_TOP_WWW . '/views/css/common.css';
                    //unset($fCSS);
                    /*$topJS[] = '/' . Z_TOP_WWW . '/views/js/sea.js';
                    $topJS[] = '/ext/jquery/jquery-1.12.0.min.js';
                    $topJS[] = '/ext/avalon/avalon.js';
                    $topJS[] = '/ext/bootstrap/js/bootstrap.min.js';
                    $topJS[] = '';*/

                    //$footJS[] = '/' . Z_TOP_WWW . '/views/js/js/sea.js';
                    //unset($topJS, $footJS);
                    $public_name = str_replace($viewsPath, '', preg_replace('@.tpl.php$@', '', $html->tplContent));
                    //echo $public_name;exit;
                    /**
                     * 载入额外的CSS和JS文件
                     */
                    $moreJsCss   = array();
                    $css_js_conf = $viewsPath . '/conf' . $public_name . '.conf';
                    $fArray      = array();
                    if (file_exists($css_js_conf)) {
                        $fArray = array_filter(preg_replace('@^#.+@', '', Z::Arrays()->trim(file($css_js_conf))));
                    }
                    if ($fArray) {
                        foreach ($fArray as $v) {
                            preg_match('/^([^\=]+)\=([^$]*)/',$v,$matches);
                            $_array = Z::Arrays()->trim($matches);
                            if ($_array[1] && $_array[2]) {
                                $moreJsCss[$_array[1]] = $_array[2];
                            }
                        }
                    }
                    if ($moreJsCss) {
                        if ($moreJsCss['CSS']) {
                            $fCSS = array_merge((array)$fCSS, $this->setMoreJsCss($moreJsCss['CSS'], $viewsPath, 'css'));
                        }
                        if ($moreJsCss['HEAD_JS']) {
                            $topJS = array_merge((array)$topJS, $this->setMoreJsCss($moreJsCss['HEAD_JS'], $viewsPath, 'js'));
                        }
                        if ($moreJsCss['FOOT_JS']) {
                            $footJS = array_merge((array)$footJS, $this->setMoreJsCss($moreJsCss['FOOT_JS'], $viewsPath, 'js'));
                        }
                        IF ($moreJsCss['META']) {
                            $metaArr = array_merge((array)$metaArr,explode(',',$moreJsCss['META']));
                        }
                    }
                    $html->setMeta($metaArr);
                    $html->setCss($fCSS);
                    //载入与模板同名的CSS文件
                    $current_default_css = $viewsPath . '/css' . $public_name . '.css';
                    if (file_exists($current_default_css)) {
                        $html->setCss(preg_replace('@^' . preg_quote(Z_DIR, '@') . '@', '', $current_default_css));
                    }
                    //载入与模板同名的JS文件到时【页面底部】
                    $current_default_js = $viewsPath . '/js' . $public_name . '.js';
                    if (file_exists($current_default_js)) {
                        $html->setBottomScript(preg_replace('@^' . preg_quote(Z_DIR, '@') . '@', '', $current_default_js));
                    }
                    if ($footJS) {
                        $html->setBottomScript($footJS);
                    }
                    //载入额外的头部JS文件
                    if ($topJS) {
                        $html->setTopScript($topJS);
                    }
                }
                //输出编码转换
                if (strtolower($c->dataCharset) != strtolower($c->metaCharset)) {
                    $this->data = \Z::Arrays()->iconv($c->dataCharset, $c->metaCharset, $this->data);
                }

                if (config::SMARTY_SWITCH === true) { //使用smarty模板  Z_SMARTY_SWITCH
                    /**
                     * 该变量在$c->tplMainPage模板文件中会用到
                     */
                    $smarty = $this->smartySet();
                }
                require $viewsPath . '/' . $c->tplMainPage;
            } else {
                //不设置任何模板时的数据处理
                print_r($this->data);
            }
            if ($c->htmlCache === true && $this->config->web()->htmlCacheSwitch === true) {
                $h = ob_get_contents();
                \PageStatic::createHtml($h, $c->tplContent, $c->htmlCache);
            }

            if (!$errors) {
                $gzip->ob_output();
            }
        }
    }

    private function setMoreJsCss($moreJsCss, $viewsPath, $type) {
        $fCSS = array();
        if ($moreJsCss) {
            $_arr = Z::Arrays()->trim(explode(',', $moreJsCss));
            foreach ($_arr as $_k => $_v) {
                if (basename($_v) == $_v && isset($_dir_file[$_k - 1])) {// 后面的文件若无指定路径则会取前一个文件的路径作为后面文件的所在路径如：/ext/bootstrap/css/1.css, 2.css, tmp/My/t.css。2.css和1.css的路径相同都属于/ext/bootstrap/css下面的文件！
                    $_dir_file[$_k] = dirname($_dir_file[$_k - 1]) . '/' . $_v;
                } else {
                    $_dir_file[$_k] = (strpos($_v, '/') === 0 ? $_v : preg_replace('@^' . preg_quote(Z_DIR, '@') . '@', '', $viewsPath) . '/' . $type . '/' . $_v);
                }
                $fCSS[] = $_dir_file[$_k];
            }
        }
        return $fCSS;
    }

    /**
     * smarty模板相关设置
     */
    private function smartySet() {
        require(Z_SMARTY_LIBS . '/Smarty.class.php');
        $smarty = new Smarty();

        $smarty->template_dir = Z_SMARTY_TEMPLATE_DIR;
        $smarty->compile_dir  = Z_SMARTY_COMPILE_DIR;

        if (!is_writable($smarty->compile_dir)) {
            echo $smarty->compile_dir . " Write Failure! Please check it's Write Permissions!";
            exit;
        }
        if (config::DEBUG === true) {//Z_DEBUG
            $smarty->clear_compiled_tpl(); //删除tpl_c中的模板文件，在生产站时不要用此动作
        }
        $smarty->left_delimiter  = Z_SMARTY_DELIMITER_LEFT;//'{{';
        $smarty->right_delimiter = Z_SMARTY_DELIMITER_RIGHT;//'}}';
        //$smarty->php_handling    = SMARTY_PHP_ALLOW; //允许模板页里执行PHP代码
        $smarty->caching        = false; //启用缓存否【绝对不要开启，产品列表那里会有问题的。我们不用smarty的缓存！】
        $smarty->cache_lifetime = 3600; //缓存1小时
        $smarty->cache_dir      = _SMARTY_TPLC_ . 'cache'; //缓存保存目录

        if ($smarty->caching === true && !file_exists($smarty->cache_dir)) {  //创建缓存目录
            mkdir($smarty->cache_dir, 0700);
        }

        return $smarty;
    }

    /**
     * 404 处理
     * 注意：一般情况下在(new \Url())->parseUrl();中已经处理了各个页面的路由关系，此处就处理404即可！
     * @param $e
     * @throws \core\models\Error|\core\models\Exception404
     */
    public function notFound($e) {
        header("HTTP/1.1 404 Not Found");
        header("Status: 404 Not Found");
        //die($REQUEST_URI.'子控制器的404处理！');
        $_POST[$this->arg_controller_name] = 'page404';
        $_POST[$this->arg_action_name]     = 'index';
        $this->runController();
    }
}